home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Networking / OTLookupNameTest1.0d1 / OTLookupNameTest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-14  |  6.7 KB  |  243 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        OTLookupNameTest.c
  3.  
  4.     Contains:    A simple illustration of how to use OTLookupName.
  5.  
  6.     Written by:    Quinn "The Eskimo!"
  7.  
  8.     Copyright:    © 1997 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.     You may incorporate this sample code into your applications without
  13.     restriction, though the sample code has been provided "AS IS" and the
  14.     responsibility for its operation is 100% yours.  However, what you are
  15.     not permitted to do is to redistribute the source as "DSC Sample Code"
  16.     after having made changes. If you're going to re-distribute the source,
  17.     we require that you make it clear in the source that the code was
  18.     descended from Apple Sample Code, but that you've made changes.
  19. */
  20.  
  21. /////////////////////////////////////////////////////////////////////
  22. // The OT debugging macros in <OTDebug.h> require this variable to
  23. // be set.
  24.  
  25. #ifndef qDebug
  26. #define qDebug    1
  27. #endif
  28.  
  29. /////////////////////////////////////////////////////////////////////
  30. // Pick up all the standard OT stuff.
  31.  
  32. #include <OpenTransport.h>
  33.  
  34. /////////////////////////////////////////////////////////////////////
  35. // Pick up all the OT AppleTalk stuff.
  36.  
  37. #include <OpenTptAppleTalk.h>
  38.  
  39. /////////////////////////////////////////////////////////////////////
  40. // Pick up the OTDebugBreak and OTAssert macros.
  41.  
  42. #include <OTDebug.h>
  43.  
  44. /////////////////////////////////////////////////////////////////////
  45. // Standard C prototypes.
  46.  
  47. #include <stdio.h>
  48.  
  49. /////////////////////////////////////////////////////////////////////
  50. // OTDebugStr is not defined in any OT header files, but it is
  51. // exported by the libraries, so we define the prototype here.
  52.  
  53. extern pascal void OTDebugStr(const char* str);
  54.  
  55. /////////////////////////////////////////////////////////////////////
  56.  
  57. static UInt32 gLastPrinted = 0;
  58.  
  59. static pascal void YieldingNotifier(EndpointRef ep, OTEventCode code, 
  60.                                        OTResult result, void* cookie)
  61.     // This notifier calls printf on a period basis in response
  62.     // to a kOTSyncIdleEvent.  By the wonders of SIOUX, printf calls
  63.     // WaitNextEvent for us, and hence our synchronous calls to 
  64.     // OT will yield to other processes.
  65. {
  66.     #pragma unused(ep)
  67.     #pragma unused(result)
  68.     #pragma unused(cookie)
  69.     
  70.     switch (code) {
  71.         case kOTSyncIdleEvent:
  72.             if (TickCount() > gLastPrinted + 10) {
  73.                 printf(".");
  74.                 fflush(stdout);
  75.                 gLastPrinted = TickCount();
  76.             }
  77.             break;
  78.         default:
  79.             // do nothing
  80.             break;
  81.     }
  82. }
  83.  
  84. /////////////////////////////////////////////////////////////////////
  85.  
  86. static void PrintAddress( DDPAddress *addr )
  87.     // Prints a DDPAddress in a nicely formatted manner.
  88. {
  89.     OTAssert( "PrintAddress: Expected a DDPNBPADdress", addr->fAddressType == AF_ATALK_DDP );
  90.     printf("Net = $%04x, Node = $%02x, Socket = $%02x ", 
  91.                 addr->fNetwork, 
  92.                 addr->fNodeID, 
  93.                 addr->fSocket);
  94. }
  95.  
  96. static void PrintName(const char *name, UInt32 length)
  97.     // Prints on NBP name in a nicely formatted manner.
  98. {
  99.     char nameForPrinting[256];
  100.     
  101.     OTMemzero(nameForPrinting, 256);
  102.     OTMemcpy(nameForPrinting, name, length);
  103.  
  104.     printf("“%s”", nameForPrinting);
  105. }
  106.  
  107. enum {
  108.     kResponseBufferSize = 8192
  109. };
  110.  
  111. static OSStatus LookupAndPrint(char *requestAddress)
  112.     // requestAddress must be an NBP address of the form
  113.     // <name>:<type>@<zone>.  This routine opens an NBP mapper
  114.     // provider, switches it into synchronous/blocking mode
  115.     // and uses sync idle events to yield time to other processes.
  116.     // It then issues an NBP lookup request using OTLookupName.
  117.     // When the request completes, it prints out the resulting
  118.     // addresses and names.
  119. {
  120.     OSStatus err;
  121.     OSStatus junk;
  122.     MapperRef nbpMapper;
  123.     TLookupRequest lookupRequest;
  124.     TLookupReply lookupReply;
  125.     UInt8 *responseBuffer;
  126.     TLookupBuffer *currentLookupReplyBuffer;
  127.     UInt32 nameIndex;
  128.     
  129.     err = noErr;
  130.     nbpMapper = kOTInvalidMapperRef;
  131.     
  132.     // Create the responseBuffer.
  133.     
  134.     responseBuffer = OTAllocMem(kResponseBufferSize);
  135.     if (responseBuffer == nil) {
  136.         err = kENOMEMErr;
  137.     }
  138.     
  139.     // Create an NBP mapper and set it to up for threaded processing.
  140.     
  141.     if (err == noErr) {
  142.         nbpMapper = OTOpenMapper(OTCreateConfiguration(kNBPName), 0, &err);
  143.     }
  144.     if (err == noErr) {
  145.         junk = OTSetSynchronous(nbpMapper);
  146.         OTAssert("LookupAndPrint: Could not set synchronous mode on mapper", junk == noErr);
  147.         junk = OTSetBlocking(nbpMapper);
  148.         OTAssert("LookupAndPrint: Could not set blocking mode on mapper", junk == noErr);
  149.         junk = OTUseSyncIdleEvents(nbpMapper, true);
  150.         OTAssert("LookupAndPrint: Could not enable sync idle events on mapper", junk == noErr);
  151.         junk = OTInstallNotifier(nbpMapper, YieldingNotifier, nil);
  152.         OTAssert("LookupAndPrint: Could not install notifier into mapper", junk == noErr);
  153.     }
  154.     
  155.     // Issue the OTLookupName synchronously.
  156.     
  157.     if (err == noErr) {
  158.         
  159.         // Set up the TLookupRequest structure.
  160.  
  161.         OTMemzero(&lookupRequest, sizeof(lookupRequest));
  162.         lookupRequest.name.buf = (UInt8 *) requestAddress;
  163.         lookupRequest.name.len = OTStrLength(requestAddress);
  164.         lookupRequest.timeout = 1000;                        // 1 second in milliseconds
  165.         lookupRequest.maxcnt = kResponseBufferSize / kNBPEntityBufferSize;
  166.  
  167.         // Set up the TLookupReply structure.
  168.         
  169.         OTMemzero(&lookupReply, sizeof(lookupReply));
  170.         lookupReply.names.buf = responseBuffer;
  171.         lookupReply.names.maxlen = kResponseBufferSize;
  172.         
  173.         // Call OT synchronously.
  174.         
  175.         err = OTLookupName(nbpMapper, &lookupRequest, &lookupReply);
  176.     }
  177.     
  178.     // Print out the contents of the responseBuffer.
  179.     
  180.     if (err == noErr) {
  181.         printf("\n");
  182.         
  183.         // Start by pointing currentLookupReplyBuffer to point to the
  184.         // beginning of the response buffer.
  185.         
  186.         currentLookupReplyBuffer = (TLookupBuffer *) responseBuffer;
  187.         
  188.         // For each response in the buffer...
  189.         
  190.         for (nameIndex = 0; nameIndex < lookupReply.rspcount; nameIndex++) {
  191.  
  192.             // ... print the name and address and...
  193.         
  194.             printf("%3d ", nameIndex);
  195.             PrintAddress( (DDPAddress *) ¤tLookupReplyBuffer->fAddressBuffer[0]);
  196.             PrintName( (char *) ¤tLookupReplyBuffer->fAddressBuffer[currentLookupReplyBuffer->fAddressLength], currentLookupReplyBuffer->fNameLength);
  197.             printf("\n");
  198.             
  199.             // ... use OTNextLookupBuffer to get from the current buffer to the next.
  200.             
  201.             currentLookupReplyBuffer = OTNextLookupBuffer(currentLookupReplyBuffer);
  202.         }
  203.     }
  204.     
  205.     // Clean up.
  206.     
  207.     if (responseBuffer != nil) {
  208.         OTFreeMem(responseBuffer);
  209.     }
  210.     if (nbpMapper != kOTInvalidMapperRef) {
  211.         junk = OTCloseProvider(nbpMapper);
  212.         OTAssert("LookupAndPrint: Failed closing mapper", junk == noErr);
  213.     }
  214.     
  215.     return (err);
  216. }
  217.  
  218. /////////////////////////////////////////////////////////////////////
  219.  
  220. void main(void)
  221. {
  222.     OSStatus err;
  223.     char requestAddress[] = "=:AFPServer@*";
  224.     
  225.     printf("Hello Cruel World!\n");
  226.     
  227.     err = InitOpenTransport();
  228.     
  229.     if (err == noErr) {
  230.     
  231.         err = LookupAndPrint(requestAddress);
  232.         
  233.         CloseOpenTransport();
  234.     }
  235.     
  236.     if (err == noErr) {
  237.         printf("Success.\n");
  238.     } else {
  239.         printf("Failed with error %d.\n", err);
  240.     }
  241.     printf("Done.  Press command-Q to Quit.\n");
  242. }
  243.